﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using BitPortal.Models;
namespace BitPortal.Business
{
    public static partial class UserBLL
    {
        public static void CreateAdmin(string userName, string password, string email, UserInfo info, string[] roles)
        {
            CreateUser(userName, password, email, info, roles, true);
        }

        /// <summary>
        /// Tao tai khoan nguoi dung
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="password"></param>
        /// <param name="email"></param>
        /// <param name="info"></param>
        /// <param name="roles"></param>
        /// <param name="createAsAdmin"></param>
        public static void CreateUser(string userName, string password, string email, UserInfo info, string[] roles, bool createAsAdmin = false)
        {
            if (userName.Length < 5 || userName.Length > 250)
            {
                throw new Exception("Tên đăng nhập hợp lệ từ 5 tới 250 ký tự");
            }
            if (email.Length < 10 || email.Length > 250)
            {
                throw new Exception("Email hợp lệ từ 5 tới 250 ký tự");
            }
            if (Membership.GetUser(userName) != null)
            {
                throw new Exception("Tên đăng nhập đã tồn tại!");
            }
            if (Membership.FindUsersByEmail(email).Count > 0)
            {
                throw new Exception("Email đã được xử dụng!");
            }
            if (password.Length < 6)
            {
                throw new Exception("Password phải có ít nhất 6 ký tự.");
            }
            MembershipCreateStatus status = new MembershipCreateStatus();
            MembershipUser user = Membership.CreateUser(userName, password, email, "Question?", "Answer", true, out status);

            if (status == MembershipCreateStatus.Success)
            {
                //Add roles

                if (roles != null)
                {
                    if (createAsAdmin && !roles.Contains("Admin")) Roles.AddUserToRole(userName, "Admin");
                    Roles.AddUserToRoles(userName, roles);
                }
                //Create user info
                if (info != null)
                {
                    ExtendedBitPortalEntities bitEnt = new ExtendedBitPortalEntities();
                    aspnet_Users asp_user = bitEnt.aspnet_Users.SingleOrDefault(ent => ent.UserName == user.UserName);
                    info.aspnet_Users = asp_user;
                    bitEnt.UserInfos.AddObject(info);
                    bitEnt.SaveChanges();
                }
            }
        }

        public static void UpdateAdmin(string userName, string email, UserInfo info, string[] roles)
        {
            UpdateUser(userName, email, info, roles, true);
        }

        /// <summary>
        /// Cap nhat tai khoan nguoi dung
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="email"></param>
        /// <param name="info"></param>
        /// <param name="roles"></param>
        /// <param name="updateAsAdmin"></param>
        public static void UpdateUser(string userName, string email, UserInfo info, string[] roles, bool updateAsAdmin = false)
        {
            MembershipUser user = Membership.GetUser(userName);
            if (user == null)
            {
                throw new Exception("Tài khoản không tồn tại.");
            }
            user.Email = email;
            Membership.UpdateUser(user);
            //Update Roles
            //First Remove all roles
            Roles.RemoveUserFromRoles(user.UserName, Roles.GetRolesForUser(user.UserName));
            //Add new Roles
            if (updateAsAdmin && !roles.Contains("Admin")) Roles.AddUserToRole(user.UserName, "Admin");
            if (roles != null && roles.Length > 0)
            {
                Roles.AddUserToRoles(user.UserName, roles);
            }
            //Update info
            ExtendedBitPortalEntities bitEnt = new ExtendedBitPortalEntities();
            UserInfo uInfo = bitEnt.UserInfos.SingleOrDefault(ent => ent.aspnet_Users.UserName == user.UserName);
            if (uInfo != null)
            {
                uInfo.FirstName = info.FirstName;
                uInfo.LastName = info.LastName;
                uInfo.Gender = info.Gender;
                uInfo.Address = info.Address;
                uInfo.Age = info.Age;
                uInfo.Bithday = info.Bithday;
                uInfo.City = info.City;
                uInfo.IdentityNumber = info.IdentityNumber;
                bitEnt.SaveChanges();
            }

        }

        public static int LockUser(string userName)
        {
            ExtendedBitPortalEntities bitEnt = new ExtendedBitPortalEntities();
            aspnet_Users user = bitEnt.aspnet_Users.SingleOrDefault(ent => ent.UserName == userName);
            if (user != null)
            {
                user.aspnet_Membership.IsLockedOut = true;
            }
            return bitEnt.SaveChanges();
        }

        public static int LockUser(string[] userNames)
        {
            ExtendedBitPortalEntities bitEnt = new ExtendedBitPortalEntities();
            foreach (string userName in userNames)
            {
                aspnet_Users user = bitEnt.aspnet_Users.SingleOrDefault(ent => ent.UserName == userName);
                if (user != null)
                {
                    user.aspnet_Membership.IsLockedOut = true;
                }
            }
            return bitEnt.SaveChanges();
        }

        /// <summary>
        /// Lay thong tin nguoi dung
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public static UserInfo GetUserInfo(this MembershipUser user)
        {
            var id = new Guid(user.ProviderUserKey.ToString());
            return (new ExtendedBitPortalEntities()).UserInfos.SingleOrDefault(ent => ent.CustomerID.Equals(id));
        }

        /// <summary>
        /// Lay thong tin nguoi dung theo UserName
        /// </summary>
        /// <param name="username"></param>
        /// <returns></returns>
        public static UserInfo GetUserInfo(string username)
        {
            return (new ExtendedBitPortalEntities()).UserInfos.SingleOrDefault(ent => ent.aspnet_Users.UserName == username);
        }

        public static MembershipUser GetUserByNameOrEmail(string key)
        {
            try
            {
                MembershipUser user = Membership.GetUser(key);
                if (user == null)
                {
                    user = Membership.GetUser(Membership.GetUserNameByEmail(key));
                }
                return user;
            }
            catch (Exception ex)
            {
                return null;
            }
        }

        /// <summary>
        /// Dat lai password, gui vao email nguoi dung
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static string ResetPassword(string key)
        {
            MembershipUser user = GetUserByNameOrEmail(key);
            if (user == null)
            {
                throw new Exception("Tài khoản không tồn tại");
            }
            if (!user.IsApproved)
            {
                throw new Exception("Tài khoản chưa được kích hoạt");
            }
            if (user.IsLockedOut)
            {
                throw new Exception("Tài khoản đã bị khóa");
            }
            string OldPass = "123456789";
            string newPass = user.ResetPassword();
            //Sent password to email
            try
            {
                string emailTemplate = PortalConfigBLL.GetValueByName("PasswordRecovery.EmailTemplate") as string;
                emailTemplate = emailTemplate.Replace("{UserName}", user.UserName).Replace("{NewPassword}", newPass);
                Utils.EmailUtils.SendEmailHtml((string)PortalConfigBLL.GetValueByName("DefaultAdminEmail"), new string[] { user.Email }, (string)PortalConfigBLL.GetValueByName("PasswordRecovery.EmailSubject"), emailTemplate);
                return newPass;
            }
            catch (Exception ex)
            {
                user.ChangePassword(newPass, OldPass);
                throw ex;
            }
        }

        public static string ChangePassword(string oldPass, string newPass)
        {
            MembershipUser user = Membership.GetUser();
            if (user.ChangePassword(oldPass, newPass))
            {
                try
                {
                    string emailTemplate = PortalConfigBLL.GetValueByName("PasswordChange.EmailTemplate") as string;
                    emailTemplate = emailTemplate.Replace("{UserName}", user.UserName).Replace("{NewPassword}", newPass);
                    Utils.EmailUtils.SendEmailHtml((string)PortalConfigBLL.GetValueByName("DefaultAdminEmail"), new string[] { user.Email }, (string)PortalConfigBLL.GetValueByName("PasswordChange.EmailSubject"), emailTemplate);
                }
                catch { }
                return newPass;
            }
            return null;
        }

        public static List<MembershipUser> GetAll(bool showRootAdmin = false)
        {
            var userC = Membership.GetAllUsers();
            MembershipUser[] userArray = new MembershipUser[userC.Count];
            userC.CopyTo(userArray, 0);
            var userList = userArray.ToList();
            if (!showRootAdmin) userList.RemoveAll(ent => Roles.IsUserInRole(ent.UserName, "RootAdmin"));
            return userList;
        }

        public static List<MembershipUser> GetByRole(string role, bool showRootAdmin = false)
        {
            var userC = GetAll(showRootAdmin);
            userC.RemoveAll(ent => !Roles.IsUserInRole(ent.UserName,role));
            return userC;
        }


        public static String[] GetMailForWork(String manager, String employees)
        {
            String[] strs = null;
            MembershipUser managerUser = UserBLL.GetUserByNameOrEmail(manager);
            if (manager != null)
            {
                ExtendedBitPortalEntities ent = new ExtendedBitPortalEntities();
                strs[0] = managerUser.Email;
                int index = 1;
                String[] employeesNames = (employees + ",").Split(',');
                foreach (string item in employeesNames )
                {
                    MembershipUser employeeUser = UserBLL.GetUserByNameOrEmail(item.Trim());
                    if (employeeUser!=null)
                    {
                        strs[index] = employeeUser.Email;
                        index++;
                    }
                }
            }

            return strs;
        }

    }
}